//! `std::num` 模块的测试用例
//!
//! 本文件包含对 `std::num` 中数值类型的测试，
//! 包括整数类型的溢出操作、原子整数类型等。

#[cfg(test)]
mod tests {
    use std::num::{NonZeroU32, Wrapping};
    use std::sync::atomic::{AtomicU32, Ordering};
    use std::thread;

    // --- 整数溢出操作 ---

    /// 测试 `wrapping_*` 方法 (回绕)
    #[test]
    fn test_wrapping_operations() {
        let max = u8::MAX; // 255

        // 255 + 1 回绕到 0
        assert_eq!(max.wrapping_add(1), 0);
        // 0 - 1 回绕到 255
        assert_eq!(0u8.wrapping_sub(1), 255);
    }

    /// 测试 `Wrapping` 类型
    #[test]
    fn test_wrapping_type() {
        let mut a = Wrapping(u8::MAX);
        let b = Wrapping(1u8);

        a += b; // 溢出并回绕
        assert_eq!(a.0, 0);
    }

    /// 测试 `checked_*` 方法 (检查溢出)
    #[test]
    fn test_checked_operations() {
        let max = u8::MAX;

        // 正常加法
        assert_eq!(10u8.checked_add(20), Some(30));
        // 溢出时返回 None
        assert_eq!(max.checked_add(1), None);
    }

    /// 测试 `saturating_*` 方法 (饱和)
    #[test]
    fn test_saturating_operations() {
        let max = u8::MAX;

        // 溢出时停留在边界值
        assert_eq!(max.saturating_add(10), max);
        assert_eq!(0u8.saturating_sub(10), 0);
    }

    /// 测试 `overflowing_*` 方法 (返回元组)
    #[test]
    fn test_overflowing_operations() {
        let max = u8::MAX;

        // (结果, 是否溢出)
        assert_eq!(max.overflowing_add(1), (0, true));
        assert_eq!(10u8.overflowing_add(20), (30, false));
    }

    // --- 非零数值类型 ---

    /// 测试 `NonZeroU32`
    #[test]
    fn test_nonzero_integer() {
        // 从非零值创建
        let nz_u32 = NonZeroU32::new(42).unwrap();
        assert_eq!(nz_u32.get(), 42);

        // 尝试从零创建会返回 None
        assert!(NonZeroU32::new(0).is_none());
    }

    // --- 原子类型 ---

    /// 测试 `AtomicU32` 的基本操作
    #[test]
    fn test_atomic_integer() {
        let atomic_num = AtomicU32::new(10);

        // 加载值
        assert_eq!(atomic_num.load(Ordering::SeqCst), 10);

        // 存储值
        atomic_num.store(20, Ordering::SeqCst);
        assert_eq!(atomic_num.load(Ordering::SeqCst), 20);

        // 原子加法
        atomic_num.fetch_add(5, Ordering::SeqCst);
        assert_eq!(atomic_num.load(Ordering::SeqCst), 25);

        // 比较并交换
        let result = atomic_num.compare_exchange(25, 30, Ordering::SeqCst, Ordering::Relaxed);
        assert!(result.is_ok());
        assert_eq!(atomic_num.load(Ordering::SeqCst), 30);
    }

    /// 在多线程中测试原子操作
    #[test]
    fn test_atomic_in_threads() {
        let atomic_counter = AtomicU32::new(0);
        // 需要 Arc 来在线程间共享所有权
        let arc_counter = std::sync::Arc::new(atomic_counter);

        let mut handles = vec![];

        for _ in 0..10 {
            let counter_clone = std::sync::Arc::clone(&arc_counter);
            let handle = thread::spawn(move || {
                for _ in 0..100 {
                    counter_clone.fetch_add(1, Ordering::SeqCst);
                }
            });
            handles.push(handle);
        }

        for handle in handles {
            handle.join().unwrap();
        }

        // 10 个线程，每个线程加 100 次
        assert_eq!(arc_counter.load(Ordering::SeqCst), 1000);
    }
}
